package com.midian.controller.file;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.midian.common.utils.FUtil;

/**
 * 文件控制器
 * @author Mengfh
 *
 */
@Controller
public class FileController {

	private static final Logger LOG = Logger.getLogger(FileController.class);
	
	/**
	 * 下载文件
	 * @param request
	 * @param response
	 * @param fileName
	 * @return
	 */
	@RequestMapping(value = "/file/{fileName}", method = RequestMethod.GET)
	public ModelAndView getImg(HttpServletRequest request, HttpServletResponse response, 
			@PathVariable("fileName") String fileName) {
		InputStream in = null;
		BufferedOutputStream bos = null;
		PrintWriter pw = null;
		try {
			request.setCharacterEncoding("UTF-8");
			FUtil fUtil = new FUtil();
			Object[] fileObject = fUtil.downloadFileWithLength(fileName);
			if(fileObject != null && fileObject.length > 0) {
				in = (InputStream) fileObject[0];
				if (in != null) {
					long fileLength = Long.parseLong(fileObject[1].toString());
					response.setHeader("Content-Length", String.valueOf(fileLength));
					bos = new BufferedOutputStream(response.getOutputStream());
					byte[] buff = new byte[2048];
					int bytesRead;
					while (-1 != (bytesRead = in.read(buff, 0, buff.length))) {
						bos.write(buff, 0, bytesRead);
					}
				} else {
					response.setContentType("text/html;charset=utf-8");
					response.sendError(404);
					try {
						pw = response.getWriter();
					} catch (IOException e) {
						LOG.error(e.getMessage());
					}
					pw.print("file_non_existent");
				}
			}
		} catch (Exception e) {
			LOG.error(e.getMessage());
		} finally {
			try {
				if(in != null) {
					in.close();
				}
			} catch (IOException e) {
				LOG.error(e.getMessage());
			}
			try {
				if(bos != null) {
					bos.close();
				}
			} catch (IOException e) {
				LOG.error(e.getMessage());
			}
			if(pw != null) {
				pw.close();
			}
		}
		return null;
	}

	/**
	 * 断点下载文件
	 * @param request
	 * @param response
	 * @param fileName
	 * @return
	 */
	@RequestMapping(value = "/fileResume/{fileName}", method = RequestMethod.GET)
	public ModelAndView getFile(HttpServletRequest request,
			HttpServletResponse response, @PathVariable("fileName") String fileName) {
		try {
			InputStream in = null;
			BufferedOutputStream bos = null;
			request.setCharacterEncoding("UTF-8");
			FUtil fUtil = new FUtil();
			in = fUtil.downloadFile(fileName);
			Object[] fileObject=fUtil.downloadFileWithLength(fileName);
			in=(InputStream)fileObject[0];
			if (in != null) {
				long p = 0;
                long fileLength;
                fileLength = Long.parseLong(fileObject[1].toString());
                // tell the client to allow accept-ranges
                response.reset();
                response.setHeader("Accept-Ranges", "bytes");
                 
                // client requests a file block download start byte
                if (request.getHeader("Range") != null) {                                
                    response.setStatus(javax.servlet.http.HttpServletResponse.SC_PARTIAL_CONTENT);
                    p = Long.parseLong(request.getHeader("Range").replaceAll("bytes=", "").replaceAll("-", ""));                                
                }
                // support multi-threaded download
                // respone format:
                // Content-Length:[file size] - [client request start bytes from file block]
                response.setHeader("Content-Length", new Long(fileLength - p).toString());
                 
                if (p != 0) {
                    // 断点开始
                    // 响应的格式是:
                    // Content-Range: bytes [文件块的开始字节]-[文件的总大小 - 1]/[文件的总大小]
                    String contentRange = new StringBuffer("bytes ")
                            .append(new Long(p).toString())
                            .append("-")
                            .append(new Long(fileLength - 1).toString())
                            .append("/")
                            .append(new Long(fileLength).toString())
                            .toString();
                    response.setHeader("Content-Range", contentRange);
                    // pointer move to seek
                    in.skip(p);
                }
                bos = new BufferedOutputStream(response.getOutputStream());
				byte[] buff = new byte[2048];
				int bytesRead;
				while (-1 != (bytesRead = in.read(buff, 0, buff.length))) {
					bos.write(buff, 0, bytesRead);
				}
				in.close();
				bos.close();
			} else {
				response.setContentType("text/html;charset=utf-8");
				response.sendError(404);
				PrintWriter pw = null;
				try {
					pw = response.getWriter();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
				pw.print("file_non_existent");
				pw.flush();
				pw.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

}
